package com.amber.proyecto.envia.imagenes.sw.usuario;

import java.io.BufferedOutputStream;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;

import android.R;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.support.v4.util.LruCache;
import android.widget.ImageView;

import com.amber.proyecto.envia.imagenes.sw.usuario.MainActivity.ListAdapter;


public class Cache {
    private LruCache<String, Bitmap> mBitmapCache;
    private ArrayList<String> mCurrentTasks;
    private int mMaxWidth;
    private int mMaxHeight;

    public Cache(int size, int maxWidth, int maxHeight) {
            mMaxWidth = maxWidth;
            mMaxHeight = maxHeight;

            mBitmapCache = new LruCache<String, Bitmap>(size) {
                    @Override
                    protected int sizeOf(String key, Bitmap b) {
                            // Assuming that one pixel contains four bytes.
                            return b.getHeight() * b.getWidth() * 4;
                    }
            };

            mCurrentTasks = new ArrayList<String>();
    }

    private void addBitmapToCache(String key, Bitmap bitmap) {
            if (getBitmapFromCache(key) == null) {
                    mBitmapCache.put(key, bitmap);
            }
    }

    private Bitmap getBitmapFromCache(String key) {
            return mBitmapCache.get(key);
    }

    /**
     * Gets a bitmap from cache. <br/>
     * <br/>
     * If it is not in cache, this method will: <br/>
     * <b>1:</b> check if the bitmap url is currently being processed in the
     * BitmapLoaderTask and cancel if it is already in a task (a control to see
     * if it's inside the currentTasks list). <br/>
     * <b>2:</b> check if an internet connection is available and continue if
     * so. <br/>
     * <b>3:</b> download the bitmap, scale the bitmap if necessary and put it
     * into the memory cache. <br/>
     * <b>4:</b> Remove the bitmap url from the currentTasks list. <br/>
     * <b>5:</b> Notify the ListAdapter.
     * 
     * @param mainActivity
     *            - Reference to activity object, in order to call
     *            notifyDataSetChanged() on the ListAdapter.
     * @param imageKey
     *            - The bitmap url (will be the key).
     * @param imageView
     *            - The ImageView that should get an available bitmap or a
     *            placeholder image.
     * @param isScrolling
     *            - If set to true, we skip executing more tasks since the user
     *            probably has flinged away the view.
     */
    public void loadBitmap(MainActivity mainActivity, String imageKey,
                    ImageView imageView, boolean isScrolling) {
            final Bitmap bitmap = getBitmapFromCache(imageKey);

            if (bitmap != null) {
                    imageView.setImageBitmap(bitmap);
            } else {
                    imageView.setImageResource(R.drawable.btn_plus);
                    if (!isScrolling && !mCurrentTasks.contains(imageKey)
                                    && mainActivity.internetIsAvailable()) {
                            BitmapLoaderTask task = new BitmapLoaderTask(imageKey,
                                            mainActivity.getAdapter());
                            task.execute();
                    }
            }
    }

    private class BitmapLoaderTask extends AsyncTask<Void, Void, Bitmap> {
            private ListAdapter mListAdapter;
            private String mImageKey;

            public BitmapLoaderTask(String imageKey, ListAdapter adapter) {
                    mListAdapter = adapter;
                    mImageKey = imageKey;
            }

            @Override
            protected void onPreExecute() {
                    mCurrentTasks.add(mImageKey);
            }

            @Override
            protected Bitmap doInBackground(Void... params) {
                   // = new WeakReference<Bitmap>(null);
                    try {
                            URL url = new URL(mImageKey);
                            HttpURLConnection connection = (HttpURLConnection) url
                                            .openConnection();
                            connection.connect();
                            
                            BitmapFactory.Options bfOpt = new BitmapFactory.Options();
                    		bfOpt.inScaled = true;
                    		bfOpt.inSampleSize = 40;
                    		bfOpt.inPurgeable = true;
                    		                            
                    		WeakReference<Bitmap> b = new WeakReference<Bitmap>(BitmapFactory.decodeStream(connection.getInputStream(),null,bfOpt));

                            if (b != null) {
                                    int width = b.get().getWidth();
                                    int height = b.get().getHeight();

                                    if (width >= mMaxWidth || height >= mMaxHeight) {
                                            while (true) {
                                                    if (width <= mMaxWidth || height <= mMaxHeight) {
                                                            break;
                                                    }
                                                    width /= 2;
                                                    height /= 2;
                                            }
                                            b = new WeakReference<Bitmap>(Bitmap.createScaledBitmap(b.get(), width, height, false));
                                    }

                                    connection.disconnect();
                                    addBitmapToCache(mImageKey, b.get());
                                    System.gc();
                                    return b.get();
                            }
                            return null;
                    } catch (IOException e) {
                            if (e != null) {
                                    e.printStackTrace();
                            }
                            return null;
                    }
            }

            @Override
            protected void onPostExecute(Bitmap param) {
                    mCurrentTasks.remove(mImageKey);
                    if (param != null) {
                            mListAdapter.notifyDataSetChanged();
                    }
            }
    }

    public void clear() {
            mBitmapCache.evictAll();
    }

}